#-*- coding: utf-8 -*-
import httplib
import logging
import selenium

from selenose.consts import LOGGER
from selenose.excepts import DriverError
from selenose.tools import gettell, getcontent

# Get a logger
logger =  logging.getLogger('%s.%s' % (LOGGER, __name__))

class Driver(object):
    
    def __init__(self, url, fixtures=None):
        self.url = url
        self.fixtures = fixtures
        self.did = None
        self.host = None
        self.port = None
        self.django = None
        self.databases = None
        self.log = None
        self.sel = None
        self.tell = None
        
    def initialize(self, environ, url=None):
        if not self.check(throw=False):
            from django.db import connections
            from django.utils import simplejson
            data = simplejson.loads(self.post('start', {True: [], False: self.fixtures, }[self.fixtures is None]))
            self.host = data['host']
            self.port = data['port']
            self.django = data['django']
            self.did = data['id']
            self.databases = data['databases']
            self.log = data['log']
            self.tell = gettell(self.log)
            for connection in connections._connections.values():
                connection.close()
            for alias, database in self.databases.items():
                connections.databases[alias]['ENGINE'] = 'django.db.backends.sqlite3'
                connections.databases[alias]['NAME']   = database
            connections._connections = {}
            self.sel = selenium.selenium(self.host, self.port, environ, self.geturl(url))
        return self.sel

    def check(self, throw=True):
        if self.did is None \
                or self.host is None \
                or self.port is None \
                or self.django is None \
                or self.sel is None \
                or self.databases is None \
                or self.log is None \
                or self.tell is None:
            if throw: raise DriverError('call start on driver first')
            else: return False
        return True
    
    def stop(self):
        if self.check(False):
            try: self.sel.stop()
            except BaseException: pass
            self.post('stop', self.did)
            self.clean()
    
    def clean(self):
        self.sel = None
        self.did = None
        self.host = None
        self.port = None
        self.django = None
        self.databases = None
        self.log = None
        self.tell = None
    
    def geturl(self, url=None):
        if url is None:
            return self.django
        elif url.startswith('http://') or url.startswith('https://'):
            return url
        else:
            base = self.django
            if base.endswith('/'): base = base[:-1]
            slash = {True: '', False: '/'}[url.startswith('/')]
            return '%s%s%s' % (base, slash, url)
    
    def post(self, action, data='nothing'):
        from django.utils import simplejson
        jdata = simplejson.dumps(data)
        logger.debug('driver ask %s on %s with data %s' % (action, self.url, jdata))
        conn = httplib.HTTPConnection(self.url)
        conn.request('POST', '/%s' % action, jdata, {'Content-Type': 'text/json', 'Content-Length': len(jdata), })
        resp = conn.getresponse()
        if resp.status != 200:
            conn.close()
            raise DriverError('error %d with reason %s' % (resp.status, resp.reason))
        content = resp.read()
        conn.close()
        logger.debug('driver got %s' % content)
        return content

    def getoutbox(self):
        from selenose.mail import pythonize
        from selenose.models import EmailMessage
        return [ pythonize(message.data) for message in EmailMessage.objects.order_by('date') ]

    def getlog(self):
        self.check(throw=True)
        return getcontent(self.log, self.tell)
